home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk53 / closeme / closeme.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  9KB  |  264 lines

  1. /*
  2.     CloseMe - a display hack by Charlie Gibbs
  3.  
  4.     This version was compiled on April 13, 1988.
  5.  
  6.     This program started out as a simple exercise in using
  7.     Intuition's facilities, but I decided that if I'm going to
  8.     learn about Intuition, I might as well have fun doing it.
  9.  
  10.     Special thanks goes to Larry Phillips for providing the basic
  11.     idea, and to Leo Schwab for inspiring me to such perversions.
  12.  
  13.     This program opens up a screen of its own unless you run it
  14.     from the CLI with a -w switch on the command line.  For some
  15.     reason, it bogs down horribly when running on the Workbench
  16.     screen, and steals some memory that it never gives back,
  17.     although it behaves itself when run in a screen of its own.
  18.     If anyone can tell me why it does this, I'd really appreciate it.
  19. */
  20.  
  21. #include <intuition/intuition.h>
  22.  
  23. #ifdef AZTEC_C
  24. #   include <functions.h>
  25. #endif
  26.  
  27. struct IntuitionBase *IntuitionBase;
  28. struct GfxBase *GfxBase;
  29.  
  30. #define INTUITION_REV 0
  31. #define GRAPHICS_REV  0
  32. #define IMSG    struct IntuiMessage
  33.  
  34. int SeparateScreen = 1;    /* Set to zero to play on the Workbench screen. */
  35.  
  36. SHORT bounce[] = {21, 15, 13, 9, 7, 5, 3, 1, 0};
  37.  
  38. struct NewScreen NewScreen = {
  39.     0, 0, 640, 200, 2,        /* LeftEdge, TopEdge, Width, Height, Depth */
  40.     0, 1,            /* DetailPen, BlockPen */
  41.     HIRES, CUSTOMSCREEN,    /* ViewModes, Type */
  42.     NULL,            /* Font */
  43.     (UBYTE *)"Oh no, Charlie's acting strange again.",    /* DefaultTitle */
  44.     NULL, NULL };        /* Gadgets, CustomBitMap */
  45.  
  46. struct NewWindow NewWindow = {
  47.     20, 20, 300, 50,        /* LeftEdge, TopEdge, Width, Height */
  48.     0, 1,            /* DetailPen, BlockPen */
  49.     CLOSEWINDOW | MOUSEMOVE,    /* IDCMPFlags */
  50.     WINDOWCLOSE | SMART_REFRESH | ACTIVATE | NOCAREREFRESH,    /* Flags */
  51.     NULL, NULL,            /* FirstGadget, CheckMark */
  52.     (UBYTE *)"CloseMe",        /*
  53.  Title */
  54.     NULL, NULL,            /* Screen, BitMap */
  55.     1, 1, 640, 200,        /* MinWidth, MinHeight, MaxWidth, MaxHeight */
  56.     WBENCHSCREEN } ;        /* Type */
  57.  
  58. main(argc, argv) int argc; char *argv[];
  59. {
  60.     struct Screen *Screen;
  61.     struct Window *Window;
  62.     IMSG  *message;
  63.     ULONG cl;            /* Current message class */
  64.     SHORT mx, my;        /* Current mouse co-ordinates */
  65.     SHORT dx, dy;        /* Distance to move the window */
  66.     SHORT maxx, maxy;        /* Don't move the window past here! */
  67.     BOOL mousemove;        /* We got a MOUSEMOVE event. */
  68.     int i;
  69.  
  70.     maxx = NewWindow.MaxWidth - NewWindow.Width - 20;
  71.     maxy = NewWindow.MaxHeight - NewWindow.Height - 10;
  72.  
  73. /* Open libraries (the startup module already took care of dos.library) */
  74.  
  75.     IntuitionBase = (struct IntuitionBase *)
  76.     OpenLibrary ("intuition.library", INTUITION_REV);
  77.     if (IntuitionBase == NULL)
  78.     exit (10);
  79.     GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", GRAPHICS_REV);
  80.     if (GfxBase == NULL)
  81.     exit (10)
  82. ;
  83.  
  84. /* If desired, open a custom screen to work in.
  85.     The -w command-line switch makes it go to the Workbench screen. */
  86.  
  87.     for (i = 1; i < argc; i++) {
  88.     if ((argv[i][0] == '-')
  89.     && (argv[i][2] == '\0')
  90.     && (toupper (argv[i][1]) == 'W')) {
  91.         SeparateScreen = FALSE;
  92.         break;
  93.     }
  94.     }
  95.     if (SeparateScreen) {
  96.     if ((Screen = (struct Screen *) OpenScreen (&NewScreen)) == NULL)
  97.         exit (10);
  98.     NewWindow.Screen = Screen;
  99.     NewWindow.Type = CUSTOMSCREEN;
  100.     }
  101.  
  102. /* Open a window and display some text. */
  103.  
  104.     if ((Window = (struct Window *) OpenWindow (&NewWindow)) == NULL)
  105.     exit (10);
  106.     Move (Window->RPort, 20, 20);
  107.     Text (Window->RPort, "Go ahead, try to close me.", 26);
  108.  
  109. /* If the user tries to close the window, jump out of the way.
  110.     Since the only event that can happen right now is WINDOWCLOSE,
  111.     we can Wait() for anything and not bother testing what we get. */
  112.  
  113.     Wait (1 << Window->UserPort->mp_SigBit);
  114.     MoveWindow (Window, 100L, 60L);
  115.     NewWindow.LeftEdge += 100;
  116.     NewWindow.TopEdge += 60;
  117.     Move (Window->RPort, 20, 20);
  118.     Text (Window->RPort, "Ha ha, you missed.  Try again.", 30);
  119.  
  120. /* Jump away when he tries the next time too. */
  121.  
  122.     Wait (1 << Window->UserPort->mp_SigBit);
  123.     MoveWindow (Window, 100L, -30L);
  124.     NewWindow.LeftEdge += 100;
  125.     NewWindow.TopEdge -= 30;
  126.     Move (Window->RPort, 20, 20);
  127.     Text (Window->RPort, "Catch me if you can!          ", 30);
  128.  
  129. /* Run away from the mouse.  We CAN be cornered, though. */
  130.  
  131.     ReportMouse (TRUE, Window);    /* Turn on reporting of mouse movements. */
  132.     mousemove = FALSE;
  133.     FOREVER {
  134.     Wait (1 << Window->UserPort->mp_SigBit);    /* Wait for action. */
  135.     while (message = (IMSG *)GetMsg (Window->UserPort)) {
  136.         if ((cl = message->Class) & MOUSEMOVE) {
  137.         mousemove = TRUE;        /* It's a mouse movement. */
  138.         mx = message->MouseX;        /* Save mouse co-ordinates. */
  139.         my = message->MouseY;
  140.         }
  141.         ReplyMsg (message);        /* Reply ASAP - there might be more! */
  142.  
  143.         if ((cl & CLOSEWINDOW)    /* If he caught the close gadget   */
  144.         && !mousemove        /*  in the middle of the screen... */
  145.         && (((NewWindow.LeftEdge > 0) && (NewWindow.LeftEdge < maxx))
  146.         || ((NewWindow.TopEdge > 0) && (NewWindow.TopEdge < maxy)))) {
  147.             mousemove = TRUE;        /*  ...fake a mouse movement. */
  148.             if (NewWindow.LeftEdge + 20 > maxx)
  149.             mx = 17;
  150.             else
  151.             mx = 15;
  152.             if (NewWindow.TopEdge + 10 > maxy)
  153.             my = 6;
  154.             else
  155.             my = 4;
  156.         }
  157.     }
  158.     if (mousemove) {
  159.         dx = mx - 16;
  160.     /* Adjust to center of close gadget. */
  161.         dy = my - 5;
  162.         if (((dx * dx) / 4 + dy * dy) < 400) {    /* If he's near it... */
  163.         if (dx > 0)
  164.             if (NewWindow.LeftEdge < 20)
  165.             dx = -NewWindow.LeftEdge;    /* Stay on screen! */
  166.             else
  167.             dx = -20;
  168.         else
  169.             if (NewWindow.LeftEdge + 20 > maxx)
  170.             dx = maxx - NewWindow.LeftEdge;
  171.             else
  172.             dx = 20;
  173.         if (dy > 0)
  174.             if (NewWindow.TopEdge < 10)
  175.             dy = -NewWindow.TopEdge;
  176.             else
  177.             dy = -10;
  178.         else
  179.             if (NewWindow.TopEdge + 10 > maxy)
  180.             dy = maxy - NewWindow.TopEdge;
  181.             else
  182.             dy = 10;
  183.         MoveWindow (Window, (long) dx, (long) dy);    /* Run away. */
  184.         NewWindow.LeftEdge += dx;    /* Remember where we are. */
  185.         NewWindow.TopEdge += dy;
  186.         }
  187.         mousemove = FALSE;
  188.     }
  189.     if ((dx == 0) && (dy == 0)    /* He cornered us... */
  190.     && (cl & CLOSEWINDOW))        /* ...and hit the close gadget. */
  191.         break;
  192.     }
  193.     ReportMouse (FALSE, Window);    /* Turn off mouse reporting. */
  194.     Move (Window->RPort, 20, 20);
  195.     Text (Window->RPort, "Arrgh!  I'm cornered!", 21);
  196.  
  197. /* Make him think he got rid of us. */
  198.  
  199.     Delay (100L);            /* Wait two seconds... */
  200.     CloseWindow (Window);        /*  ...then disappear. */
  201.     if (SeparateScreen)
  202.     CloseScreen (Screen);
  203.     Delay (150L);            /* Wait another three seconds. */
  204.     NewWindow.LeftEdge = NewWindow.TopEdge = 0;
  205.     if (SeparateScreen)
  206.     Screen = (struct Screen *) OpenScreen (&NewScreen);
  207.     Window = (struct Window *) OpenWindow (&NewWindow);
  208.     Move (Window->RPort, 20, 20);
  209.     Text (Window->RPort, "Bet you thought you had me.", 27);
  210.  
  211. /* The next time he hits the close gadget, roll up the window. */
  212.  
  213.     Wait (1 << Window->UserPort->mp_SigBit);
  214.     Move (Window->RPort, 20, 20);
  215.     Text (Window->RPort, "Augghhh!  I'm melting!     ", 27);
  216.     while (NewWindow.Height > 10) {
  217.     SizeWindow (Window, 0L, -5L);    /* Shrink vertically... */
  218.     NewWindow.Height -= 5;
  219.     }
  220.     while (NewWindow.Width > 30) {
  221.     SizeWindow (Window, -10L, 0L);    /*  ...then horizontally. */
  222.     NewWindow.Width -= 10;
  223.     }
  224.  
  225. /* Now fall and bounce across the floor. */
  226.  
  227.     Wait (1 << Window->UserPort->mp_SigBit);
  228.     for (i = 0, dy = 1; i < 190; dy += 2) {    /* Fall down... */
  229.     if (i + dy > 190)            /*  ...but don't go    */
  230.         dy = 190 - i;            /*  through the floor! */
  231.     MoveWindow (Window, 6L, (long) dy);
  232.     i += dy;
  233.     }
  234.     for (i = 0; bounce[i]; i++) {
  235.     for (dy = -bounce[i]; dy < 0; dy += 2)
  236.         MoveWindow (Window, 6L, (long) dy);        /* Bounce up. */
  237.     for (dy = 1; dy <= bounce[i]; dy += 2)
  238.         MoveWindow (Window, 6L, (long) dy);        /* Fall back down. */
  239.     }
  240.  
  241. /* Let him finally get rid of us. */
  242.  
  243.     Wait (1 << Window->UserPort->mp_SigBit);
  244.     ModifyIDCMP (Window, (long) NEWSIZE);    /* Listen for sizing only */
  245.  
  246.     while (NewWindow.Height > 1) {
  247.     SizeWindow (Window, -3L, -1L);    /* Shrink the close gadget... */
  248.     Wait (1 << Window->UserPort->mp_SigBit);
  249.     NewWindow.Height -= 1;
  250.     NewWindow.Width -= 3;
  251.     }
  252.     SizeWindow (Window, -2L, 0L);    /*  ...down to a single pixel... */
  253.     WaitPort (Window->UserPort);
  254.     message = (IMSG *)GetMsg (Window->UserPort);
  255.     ReplyMsg (message);
  256.     Delay (50);
  257.     CloseWindow (Window);        /*  ...then close it completely. */
  258.  
  259.     if (SeparateScreen)
  260.     CloseScreen (Screen);
  261.     CloseLibrary (IntuitionBase);
  262.     CloseLibrary (GfxBase);
  263. }
  264.